package com.wyp.design.pattern.creational.singleton.lazy.doublecheck;


/**
 * 懒汉式加载以及线程安全。使用双重检查，避免使用锁时，将整个类都锁了。
 *
 * @author: yipeng.wang01@hand-china.com-25490
 * @TIME: 2020/1/2/13:40
 **/
public class LazySingletonDoubleCheck {
    private static volatile LazySingletonDoubleCheck lazySingleton = null;

    private LazySingletonDoubleCheck() {
    }

    public static  LazySingletonDoubleCheck getInstance() {

        //进行双重检查，吧同步范围缩小到该方法内
        //这样操作，看似没有任何问题，但是想想，创建对象过程：时间线
        //1分配对象的内存空间--3设置instance指向内存空间---2初始化对象--4初次访问该对象
        //在创建对象这一过程存在重排序，如果这时候一个线程已经创建对象已经指向了内存空间没有初始化，另一个线程进来，进行创建对象判断是否为null，
        //结果不是，他就会得到一个初始化不完整的对象。此时有两种解决方案：
        //1.不进行重排序，（重排序目的在于不改变程序计算结果，提高效率），使用volatile.
        //2.进行重排序时对其他线程可见。


        if (lazySingleton == null) {
            synchronized (LazySingletonDoubleCheck.class) {
                if (lazySingleton == null) {
                    lazySingleton = new LazySingletonDoubleCheck();
                }
            }
        }
        return lazySingleton;
    }
}
